package com.woniu.shop.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.shop.constant.RedisConstant;
import com.woniu.shop.mapper.ShopIncomeMapper;
import com.woniu.shop.pojo.ShopIncome;
import com.woniu.shop.pojo.ShopYearIncome;
import com.woniu.shop.utils.UploadUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author LiFangyu
 * @since 2023/2/16 16:43
 */
@Component
@Slf4j
public class ScheduledTasks {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ShopIncomeMapper shopIncomeMapper;

    /**
     * Java(Spring)
     *     *    *    *    *    *    *
     *     -    -    -    -    -    -
     *     |    |    |    |    |    |
     *     |    |    |    |    |    +----- day of week (0 - 7) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
     *     |    |    |    |    +---------- month (1 - 12) OR jan,feb,mar,apr ...
     *     |    |    |    +--------------- day of month (1 - 31)
     *     |    |    +-------------------- hour (0 - 23)
     *     |    +------------------------- min (0 - 59)
     *     +------------------------------ second (0 - 59)
     */
    @Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3点执行一次
    //@Scheduled(cron = "0/15 * * * * ?") // 从启动开始每隔15秒执行一次
    public void cleanPic(){
        Set<String> difference = stringRedisTemplate.opsForSet()
                .difference(RedisConstant.ALIOSS_ALL_UPLOAD.name(), RedisConstant.ALIOSS_VALID_UPLOAD.name());
        if(difference != null){
            List<String> keys = new ArrayList<>(difference);
            log.info("开始清理无效图片{}",keys);
            UploadUtil.delete(keys);
            for (String key : keys) {
                stringRedisTemplate.opsForSet().remove(RedisConstant.ALIOSS_ALL_UPLOAD.name(), key);
            }
            log.info("清理无效图片完成");
        }else {
            log.error("清理无效图片遇到了错误，原因是：在Redis中读取不到文件");
        }
    }

    //@Scheduled(cron = "0 0 0 1 1 *") // 每年1月1日0时执行
    //@PostConstruct // 启动项目的时候先执行一次
    public void generateShopIncomeData() throws ParseException, JsonProcessingException {
        // 1.获取当前的年份和上一年的年份
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int incomeYear = calendar.get(Calendar.YEAR);
        SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy");
        Date lastYear = yearFormat.parse(String.valueOf(incomeYear - 1));
        Date thisYear = yearFormat.parse(String.valueOf(incomeYear));
        // 2.获取所有的门店
        List<String> shopIds = shopIncomeMapper.getAllShopId();
        // 3.对每个门店进行统计
        for(String shopId : shopIds){
            BigDecimal amount = new BigDecimal(0);
            LambdaQueryWrapper<ShopIncome> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ShopIncome::getShopId, shopId);
            wrapper.ge(ShopIncome::getCreatedTime, lastYear);
            wrapper.lt(ShopIncome::getCreatedTime, thisYear);
            List<ShopIncome> shopIncomes = shopIncomeMapper.selectList(wrapper);
            // 将年收益的记录保存到redis中
            ObjectMapper objectMapper = new ObjectMapper();
            String records = objectMapper.writeValueAsString(shopIncomes);
            stringRedisTemplate.opsForHash().put(RedisConstant.SHOP_YEAR_INCOME_LIST.name() + "_" + shopId, String.valueOf(incomeYear - 1), records);
            for(ShopIncome shopIncome : shopIncomes){
                amount = amount.add(shopIncome.getAmount());
            }
            ShopYearIncome shopYearIncome = new ShopYearIncome();
            shopYearIncome.setId(IdWorker.getIdStr());
            shopYearIncome.setShopId(shopId);
            shopYearIncome.setAmount(amount);
            shopYearIncome.setYear(String.valueOf(incomeYear - 1));
            shopYearIncome.setIsDeleted("0");
            shopYearIncome.setCreatedTime(new Date());
            shopYearIncome.setUpdatedTime(new Date());
            // 将年收益保存到数据库
            ShopYearIncome check = shopIncomeMapper.checkRecordExist(shopId,String.valueOf(incomeYear - 1));
            if(StringUtils.isEmpty(check)){
                shopIncomeMapper.createShopYearIncome(shopYearIncome);
            }
            // 将年收益保存到redis
            String income = objectMapper.writeValueAsString(amount);
            stringRedisTemplate.opsForHash().put(RedisConstant.SHOP_YEAR_INCOME_AMOUNT.name() + "_" + shopId, String.valueOf(incomeYear - 1), income);
        }
    }

}
